﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace HostLibrary.Hosts
{
    public class TcpClientController
    {
        private List<TcpClientController> _otherClients;

        private TcpClient _client;
        public TcpClient Client
        {
            get { return _client; }
            set
            {
                Stream = value.GetStream();
                _client = value;
            }
        }

        public NetworkStream Stream { get; private set; }
        public byte Id { get; private set; }
        public int AvailableBytesToRead { get { return _client.Available; } }

        public TcpClientController(TcpClient client, List<TcpClientController> otherClients, byte id)
        {
            _otherClients = new List<TcpClientController>();
            this.UpdateClients(otherClients);
            Client = client;
            Id = id;
        }

        public void UpdateClients(List<TcpClientController> otherClients)
        {
            _otherClients.Clear();
            foreach (TcpClientController tcc in otherClients)
            {
                _otherClients.Add(tcc);
            }
        }

        public void ClientReadAsync(int bufferSize)
        {
            //try
            {
                if (this.Stream.CanRead)
                {
                    int bytesRead = 0;
                    int lastBytes = 1;
                    byte[] readBuffer = new byte[bufferSize];
                    this.Stream.BeginRead(readBuffer, bytesRead, readBuffer.Length - bytesRead, result =>
                    {
                        lastBytes = this.Stream.EndRead(result);
                        bytesRead += lastBytes;
                        if (bytesRead < readBuffer.Length)
                        {
                            ClientReadAsync(bufferSize);
                        }
                        else if (bytesRead == readBuffer.Length)
                        {
                            ClientWriteAsync(readBuffer);
                        }
                        else
                        {
                            //this.Done = true;
                        }
                    },
                        null);
                }
                //else this.Done = true;
            }
            //catch (Exception exc)
            //{
            //    Console.WriteLine(exc.ToString());
            //    this.Done = true;
            //}
        }

        private void ClientWriteAsync(byte[] readBuffer)
        {
            int finishedWrites = 0;
            readBuffer[1] = this.Id;
            for (int i = 0; i < _otherClients.Count; i++)
            {
                if (_otherClients[i].Id != this.Id)
                {
                    NetworkStream s = _otherClients[i].Stream;
                    if (s.CanWrite)
                    {
                        s.BeginWrite(readBuffer, 0, readBuffer.Length, result =>
                        {
                            s.EndWrite(result);
                            finishedWrites++;
                            //if (finishedWrites == _otherClients.Count - 1)
                                //this.Done = true;
                        },
                            null);
                    }
                    //else this.Done = true;
                }
            }
            //if (_otherClients.Count == 1) this.Done = true;
        }
    }
}
